package com.lianxi.util;


import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.temporal.TemporalAdjuster;
import java.time.temporal.TemporalAdjusters;
import java.util.*;

/**
 * 日期工具类
 *
 * @author Administrator
 */
public class DateUtil {
    private static final Logger logger = LoggerFactory.getLogger(DateUtil.class);
    private static final String NULL = "null";

    private static final String YEAR = "yyyy";
    public static final String DEFAULT_PATTERN = "yyyy-MM-dd HH:mm:ss";


    public static String formate(Date date) {
        return format(date, "yyyy-MM-dd HH:mm:ss");
    }

    /**
     * 日期转为字符串
     *
     * @param date    日期
     * @param pattern 规则
     * @return
     */
    public static String format(Date date, String pattern) {
        if (date == null) {
            return NULL;
        }
        if (pattern == null || "".equals(pattern) || NULL.equals(pattern)) {
            pattern = "yyyy-MM-dd  HH:mm:ss";
        }
        return FastDateFormat.getInstance(pattern).format(date);
    }


    /**
     * 字符串转为日期
     *
     * @param date    字符串
     * @param pattern 规则
     * @return
     */
    public static Date format(String date, String pattern) {
        if (date == null || "".equals(date) || NULL.equals(date)) {
            return new Date();
        }
        if (pattern == null || "".equals(pattern) || NULL.equals(pattern)) {
            pattern = "yyyy-MM-dd HH:mm:ss";
        }
        Date d = null;
        try {
            d = FastDateFormat.getInstance(pattern).parse(date);
        } catch (ParseException e) {
            logger.error(">>>>>>>>>>>>parseException date {}", e.getMessage());
            e.printStackTrace();
        }
        return d;
    }

    /**
     * 字符串转为时间戳
     *
     * @param date    字符串
     * @param pattern 规则
     * @return
     */
    public static long formatLong(String date, String pattern) {
        if (date == null || "".equals(date) || NULL.equals(date)) {
            return new Date().getTime();
        }
        if (pattern == null || "".equals(pattern) || NULL.equals(pattern)) {
            pattern = "yyyy-MM-dd HH:mm:ss";
        }
        Date d = null;
        try {
            d = FastDateFormat.getInstance(pattern).parse(date);
        } catch (ParseException e) {
            logger.error(">>>>>>>>>>>>parseException date {}", e.getMessage());
            e.printStackTrace();
        }
        return d.getTime();
    }

    public static String formatWithT(String time, String pattern) {
        time = time.replace("Z", " UTC");//UTC是本地时间
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
        Date d = null;
        try {
            d = format.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        //此处是将date类型装换为字符串类型，比如：Sat Nov 18 15:12:06 CST 2017转换为2017-11-18 15:12:06
        SimpleDateFormat sf = new SimpleDateFormat(pattern);
        return sf.format(d);
    }

    public static Date format(String date) {
        return format(date, null);
    }

    public static Date addDay(Date endTime, int n) {
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(endTime);
        calendar.add(Calendar.DATE, n);
        return calendar.getTime();
    }

    public static Date subDay(Date endTime, int n) {
        if (n <= 0) {
            return endTime;
        }
        Calendar calendar = new GregorianCalendar();
        calendar.setTime(endTime);
        calendar.set(Calendar.DATE, calendar.get(Calendar.DATE) - n + 1);
        return calendar.getTime();
    }

    public static String formatStringTime(String time, String pattern) {
        if (time.length() < 9) {
            return "";
        }
        pattern = pattern.trim();
        StringBuilder sb = new StringBuilder();
        String space = pattern.replaceAll("[a-zA-Z]+", "");
        if (StringUtils.isNoneBlank(space)) {
            space = space.substring(0, 1);
        }
        try {
            if (pattern.contains(YEAR)) {
                sb.append(time.substring(0, 4));
                sb.append(space);
            }
            if (pattern.contains("yy") && !pattern.contains(YEAR)) {
                sb.append(time.substring(2, 4));
                sb.append(space);
            }
            if (pattern.contains("MM")) {
                sb.append(time.substring(5, 7));
                sb.append(space);
            }
            if (pattern.contains("dd")) {
                sb.append(time.substring(8, 10));
            }
            if (time.length() >= 9) {
                if (pattern.contains("HH")) {
                    if (pattern.contains(StringUtils.SPACE)) {
                        sb.append(StringUtils.SPACE);
                    } else {
                        sb.append(space);
                    }
                    sb.append(time.substring(11, 13));
                }
                if (pattern.contains("mm")) {
                    if (pattern.contains(StringUtils.SPACE) && !sb.toString().contains(StringUtils.SPACE)) {
                        sb.append(StringUtils.SPACE);
                    } else {
                        sb.append(space);
                    }
                    sb.append(time.substring(14, 16));
                }
                if (pattern.contains("ss")) {
                    if (pattern.contains(StringUtils.SPACE) && !sb.toString().contains(StringUtils.SPACE)) {
                        sb.append(StringUtils.SPACE);
                    } else {
                        sb.append(space);
                    }
                    sb.append(time.substring(17, 19));
                }
            }
        } catch (Exception e) {
            logger.info("time format error");
            e.printStackTrace();
        }
        return sb.toString();
    }

    public static String getDefaultStartDate(Date dNow) {
        Date dBefore = new Date();
        Calendar calendar = Calendar.getInstance(); //得到日历
        calendar.setTime(dNow);//把当前时间赋给日历
        calendar.add(Calendar.MONTH, -3);  //设置为前3月
        dBefore = calendar.getTime();   //得到前3月的时间
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd"); //设置时间格式
        String defaultStartDate = sdf.format(dBefore);    //格式化前3月的时间
        return defaultStartDate;
    }

    public static long getBeginTime(String beginTime) {
//
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long begin = 0L;
        try {
            if (StringUtils.isNotBlank(beginTime)) {
                if ("0".equals(beginTime)) {
                    return 0;
                }
                begin = format.parse(beginTime + " 00:00:00").getTime();
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return begin;
    }

    public static long getEndTime(String endTime) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        long begin = 0L;
        try {
            if (StringUtils.isNotBlank(endTime)) {
                if ("0".equals(endTime)) {
                    return 0;
                }
                begin = format.parse(endTime + " 23:59:59").getTime();
            }
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return begin;
    }

    public static String getDate(long time) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = new Date(time);
        return format.format(date);
    }

    public static String getDate2(long time) {
        /*SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date(time);
        return format.format(date);*/
        return FastDateFormat.getInstance("yyyy-MM-dd HH:mm:ss").format(time);
    }

    public static String getDateFormat(long time,String pattern) {
        /*SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = new Date(time);
        return format.format(date);*/
        return FastDateFormat.getInstance(pattern).format(time);
    }

    public static String timeStamp2Date(String seconds) {
        if (seconds == null || seconds.isEmpty() || seconds.equals("null")) {
            return "";
        }
        String format = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(new Date(Long.parseLong(seconds + "000")));
    }

    public static String getTargetDate(long time, String pattern) {
        /*SimpleDateFormat format = new SimpleDateFormat(pattern);
        Date date = new Date(time);*/
        if (time<=0){
            return "";
        }
        return FastDateFormat.getInstance(pattern).format(time);
    }

    /**
     * 通过秒数获取对应的时间
     *
     * @param seconds 秒数
     */
//    public static String getTimeBySeconds(long seconds, String timeType) {
//        String result = "";
//        try {
//            if ("m".equals(timeType)) {
//                return Long.toString(seconds / 60);
//            }
//            if ("h".equals(timeType)) {
//                return Double.toString(DecimalUtil.div(seconds, 3600, 1));
//            }
//            if ("d".equals(timeType)) {
//                return Double.toString(DecimalUtil.div(seconds, 86400, 1));
//            }
//        } catch (Exception e) {
//            e.printStackTrace();
//        }
//        return result;
//    }

    /**
     * 得到要求的开始时间
     *
     * @param days 从今天开始向前days天
     */
    public static String getBeginTime(int days) {
        if (days == -1) {
            return "";
        }
        return format(subDay(new Date(), days), "yyyy-MM-dd");
    }

    /**
     * 获得要求的时间的long型
     *
     * @param days 从今天开始向前days天
     */
    public static long getLongBeginTime(int days) {
        if (days == -1) {
            return 0;
        }
        return subDay(new Date(), days).getTime();
    }

    /**
     * 获取当天0点
     *
     * @return
     */
    public static long getTodayStartTime() {
        Calendar todayStart = Calendar.getInstance();
        todayStart.set(Calendar.HOUR, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime().getTime();
    }

    public static long getTodayStart() {
        return System.currentTimeMillis() / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset();//今天零点零分零秒的毫秒数
    }


    public static long getTodayEnd() {
        return System.currentTimeMillis() / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset() + 24 * 60 * 60 * 1000 - 1;
    }

    /*public static void main(String[] args) {
        logger.info("getTodayStart>>>>>>>>>>>>>" + getTodayStart());//昨天这一时间点
        logger.info("getTodayEnd>>>>>>>>>>>" + getTodayEnd());//当前时间
        logger.info(getTodayStartTime()+"");
        logger.info(getTodayEndTime()+"");
    }*/

    /**
     * 获取当天24点
     *
     * @return
     */
    public static long getTodayEndTime() {
        Calendar todayEnd = Calendar.getInstance();
        todayEnd.set(Calendar.HOUR, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime().getTime();
    }

    /**
     * 获得三会线索组名
     *
     * @param date 日期
     * @return
     */
    public static String getGroupName(Date date) {
        if (date == null) {
            return NULL;
        }
        String pattern = "yyyy年M月d日";
        return FastDateFormat.getInstance(pattern).format(date);
    }

    /**
     * 获得当前天的部门编码
     *
     * @param date
     * @return
     */
    public static String getGroupCode(Date date) {
        if (date == null) {
            return NULL;
        }
        String pattern = "yyyyMMdd";
        return FastDateFormat.getInstance(pattern).format(date);
    }

    /**
     * 获得当前天的部门编码
     *
     * @param date
     * @return
     */
    public static String getRecent(Date date) {
        if (date == null) {
            return NULL;
        }
        String pattern = "yyMMddHHmmss";
        return FastDateFormat.getInstance(pattern).format(date);
    }

    public static long getToLong(String DateTime)  {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date time = null;
        try {
            time = sdf.parse(DateTime);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return time.getTime();
    }

    /**
     * 判断执行时间
     *
     */
/*    public static void timeConsume(String name, long time) {
        long vg = System.currentTimeMillis() - time;
        logger.info(name + "---->执行耗时：" + BigDecimalUtil.divide((double) vg, (double) 1000L, 0) + " 秒");
    }*/

    public static long nowDay() {
        long current = System.currentTimeMillis();
        long zero = current / (1000 * 3600 * 24) * (1000 * 3600 * 24) - TimeZone.getDefault().getRawOffset();
//        System.out.println(zero);
        return zero;
    }

    //TODO 获取当前时间

    public static String firstOfWeek() {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate inputDate = LocalDate.now();
        TemporalAdjuster FIRST_OF_WEEK =
                TemporalAdjusters.ofDateAdjuster(localDate -> localDate.minusDays(localDate.getDayOfWeek().getValue() - DayOfWeek.MONDAY.getValue()));
        String weekStart = df.format(inputDate.with(FIRST_OF_WEEK));
        weekStart = weekStart + " 00:00:00";
        return weekStart;
    }
    //TODO 获取当前时间

    public static String endOfWeek() {
        DateTimeFormatter df = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate inputDate = LocalDate.now();
        TemporalAdjuster LAST_OF_WEEK =
                TemporalAdjusters.ofDateAdjuster(localDate -> localDate.plusDays(DayOfWeek.SUNDAY.getValue() - localDate.getDayOfWeek().getValue()));
        String weekEnd = df.format(inputDate.with(LAST_OF_WEEK));
        weekEnd = weekEnd + " 23:59:59";
        return weekEnd;
    }

    public static LocalDate formateLocalDate(int year, int month, int day) {
        LocalDate beginDate = LocalDate.of(year, month, day);
        return beginDate;
    }

    public static int longOfTwoDate(Date first, Date second) {
        //没有去处周六周日
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(first);
        int cnt = 0;
        while (calendar.getTime().compareTo(second) != 0) {
            calendar.add(Calendar.DATE, 1);
            cnt++;
        }
        return cnt;
    }

    /**
     * 获取某年最后一天的日期
     *
     * @param year
     * @return
     */
    public static Date getYearLast(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        calendar.roll(Calendar.DAY_OF_YEAR, -1);
        Date currYearLast = calendar.getTime();
        return currYearLast;
    }

    /**
     * 获取某年第一天
     *
     * @param year
     * @return
     */
    public static Date getYearFirst(int year) {
        Calendar calendar = Calendar.getInstance();
        calendar.clear();
        calendar.set(Calendar.YEAR, year);
        Date currYearFirst = calendar.getTime();
        return currYearFirst;
    }

    /**
     * 获取本月的开始时间或者结束时间
     *
     * @param isFirst true 本月开始时间   false本月结束时间
     * @return
     */
    public static long getStartOrEndDayOfMonth(Boolean isFirst) {
        LocalDate today = LocalDate.now();
        if (isFirst) {
            //本月的第一天
            LocalDate firstDay = today.with(TemporalAdjusters.firstDayOfYear());
            LocalDateTime localDateTime = firstDay.atTime(0, 0, 0);
            return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        } else {
            //本年的最后一天
            LocalDate lastDay = today.with(TemporalAdjusters.lastDayOfYear());
            LocalDateTime localDateTime = today.atTime(23, 59, 59);
            return localDateTime.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
        }
    }

    public static void main(String[] args) {
        long startOrEndDayOfMonth1 = getStartOrEndDayOfMonth(true);
        long startOrEndDayOfMonth = getStartOrEndDayOfMonth(false);
        System.out.println(startOrEndDayOfMonth1);
        System.out.println(startOrEndDayOfMonth);


        LocalDateTime localDateTime = LocalDateTime.of(2021, 12, 21, 0, 0, 0);
        long l = localDateTime.toInstant(ZoneOffset.of("+8")).toEpochMilli();
        Date date = new Date(l);
        System.out.println(DateUtil.format(date,null));
    }

    /**
     * 转换为cron格式的时间字符串
     * @param date date
     * @return string
     */
/*    public static String getCron(Date date) {
        if(Objects.isNull(date)){
            return "";
        }
        return FastDateFormat.getInstance(DateConstant.CRON_DATE_FORMAT).format(date);
    }*/

    /**
     * 将时间戳转换为cron
     * time为时间发生时间
     * min提前多少分钟提醒
     */
  /*  public static String getCron(long time,int type,int min) {
        ZoneId zone = ZoneId.systemDefault();
        LocalDate localDate = Instant.ofEpochMilli(time).atZone(zone).toLocalDate();
        //日程发生的时间
        LocalTime localTime = Instant.ofEpochMilli(time).atZone(zone).toLocalTime();
        //日程提醒的时间
        LocalTime localTimeBefore = localTime.minusMinutes(min);
        //提醒执行的时间
        LocalDateTime localDateTime = LocalDateTime.of(localDate, localTimeBefore);
        String hour = Integer.toString(localDateTime.getHour());
        String minute = Integer.toString(localDateTime.getMinute());
        String day = Integer.toString(localDateTime.getDayOfMonth());
        String month = Integer.toString(localDateTime.getMonthValue());
        String name = localDateTime.getDayOfWeek().name().substring(0,3);
        String year = Integer.toString(localDateTime.getYear());
        String result = "";
        if(type == 0){
           //不重复
            result = DateConstant.CRON_DATE_FORMAT_ONE.replace("mm",minute+"").replace("HH",hour).replace("dd",day).replace("MM",month).replace("yyyy",year);
        }
        if (type == 1){
            //每天
            result= DateConstant.CRON_DATE_FORMAT_DAY.replace("mm",minute+"").replace("HH",hour);
        }
        if (type == 2){
            //工作日
            result= DateConstant.CRON_DATE_FORMAT_WEEKDay.replace("mm",minute+"").replace("HH",hour);
        }
        if (type == 3){
            //每周
            result= DateConstant.CRON_DATE_FORMAT_WEEK.replace("mm",minute+"").replace("HH",hour).replace("WED",name);
        }
        if (type == 4){
            //每月
            result= DateConstant.CRON_DATE_FORMAT_MONTH.replace("mm",minute+"").replace("HH",hour).replace("dd",day);
        }
        if (type == 5){
            //每年
            result= DateConstant.CRON_DATE_FORMAT_YEAR.replace("mm",minute+"").replace("HH",hour).replace("dd",day).replace("MM",month);
        }
        return result;
    }
*/
    /**
     * 判断是周几
     * 0-周末
     */
    public static int getWeek(long time) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(time);
        return calendar.get(Calendar.DAY_OF_WEEK) - 1;
    }



}
